#include "pch.h"
#include "RenderNode.h"
#include "Actor.h"
#include "LightActor.h"

namespace mini
{
	CRenderNode::CRenderNode()
	{

	}

	CRenderNode::~CRenderNode()
	{

	}

	void CRenderNode::bindActor(CActor* pActor, UINT32 rendererType)
	{
		if (mpActor != pActor)
		{
			SafeRelease(mpActor);
			mpActor = pActor;
			mpActor->AddRef();
		}
		mRendererFlag = rendererType;
		for (auto item : pActor->getMeshUnits())
		{
			mMaterialUnits.push_back(item->getMaterialUnit());
		}
	}

	void CRenderNode::setRenderer(UINT32 rendererType)
	{
		mRendererFlag = rendererType;
	}

	UINT32 CRenderNode::getRendererFlag() const
	{
		return mRendererFlag;
	}

	CActor* CRenderNode::getActor() const
	{
		return mpActor;
	}

	void CRenderNode::pushPlaceInfo()
	{
		if (nullptr != mpActor)
		{
			mPlaceInfo.point = mpActor->getPosition();
			mPlaceInfo.rotation = mpActor->getRotation();
			mPlaceInfo.scale = mpActor->getScale();
		}
	}

	void CRenderNode::popPlaceInfo()
	{
		if (nullptr != mpActor)
		{
			mpActor->setPosition(mPlaceInfo.point);
			mpActor->setRotation(mPlaceInfo.rotation);
			mpActor->setScale(mPlaceInfo.scale);
			mpActor->updateMeshUnitMatrix(0);
		}
	}

	void CRenderNode::setRenderLayer(int nLayer)
	{
		mZbufferOffLayer = nLayer;
	}

	int CRenderNode::getRenderLayer()
	{
		return mZbufferOffLayer;
	}

	void CRenderNode::effectLight(CActor* pActor)
	{
		if (nullptr != mpActor)
		{
			if (pActor->getEntityType() == Light)
			{
				auto pLight = dynamic_cast<CLightActor*>(pActor);
				pLight->effectActor(getActor());
			}
		}
	}

	void CRenderNode::unEffectLight(CActor* pActor)
	{
		if (nullptr != mpActor)
		{
			if (pActor->getEntityType() == Light)
			{
				auto pLight = dynamic_cast<CLightActor*>(pActor);
				pLight->unEffectActor(getActor());
			}
		}
	}

	CRenderNode* CRenderNode::Clone()
	{
		mini::CRenderNode* pRenderNode = mini::GEngine->createRenderNode();
		pRenderNode->mpActor = mpActor;
		for (auto item : mMaterialUnits)
		{
			pRenderNode->mMaterialUnits.push_back(item);
		}
		pRenderNode->mRendererFlag = mRendererFlag;
		pRenderNode->mPlaceInfo = mPlaceInfo;
		pRenderNode->mZbufferOffLayer = mZbufferOffLayer;
		return pRenderNode;
	}

	void CRenderNode::setMaterialUnit(CMaterialUnit* pMaterialUnit, int index /*= -1*/)
	{
		if (-1 == index)
		{
			for (auto& item : mMaterialUnits)
			{
				item = pMaterialUnit;
			}
		}
		else
		{
			auto item = mMaterialUnits.begin();
			auto iEnd = mMaterialUnits.end();
			int i = 0;
			for ( ;item != iEnd; ++item)
			{
				if (i++ == index)
				{
					*item = pMaterialUnit;
					break;
				}
			}
		}
	}

	const std::list<CMaterialUnit*>& CRenderNode::getMaterialUnits() const
	{
		return mMaterialUnits;
	}

}

